package com.ia2014.tp.portal2.ejb.impl;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import com.ia2014.tp.portal2.dto.DepositoDto;
import com.ia2014.tp.portal2.dto.DespachoDto;
import com.ia2014.tp.portal2.dto.LogisticaDto;
import com.ia2014.tp.portal2.dto.PortalDto;
import com.ia2014.tp.portal2.ejb.ConfigRemote;
import com.ia2014.tp.portal2.entity.Deposito;
import com.ia2014.tp.portal2.entity.Despacho;
import com.ia2014.tp.portal2.entity.Logistica;
import com.ia2014.tp.portal2.entity.Portal;
import com.ia2014.tp.portal2.exception.ConfigException;
import com.ia2014.tp.portal2.transformer.TransformerModulo;

@Stateless

public class ConfigBean implements ConfigRemote {
	
	@PersistenceContext(unitName="portal")
	private EntityManager em;


	TransformerModulo transformer;
	
	public ConfigBean(){
		this.transformer = new TransformerModulo();
	}
	
	@Override
	public boolean crearPortal(PortalDto portal) throws ConfigException {
		
		boolean creado=false;
		
		//this.em.getTransaction().begin(); //Ignacio Iljin
		
				
		if (portal!=null){
			
			Portal portalEntity= this.transformer.toPortalEntity(portal);
			
			try {
				
				if (buscarPortal(portal.getIdModulo()) == null){
					this.em.persist(portalEntity);
					creado=true;
				}
				else{
					//altualiza el portal
					actualizarPortal(portal);
					creado = false;
				}
				
				//Le indica al Negocio que actualice la configuracion
				//actualizarNegocio();
				
			} catch (Exception e) {
				
				/*if (this.em.getTransaction().isActive()){
					this.em.getTransaction().rollback();
				}*/
				
				throw new ConfigException("No se puedo insertar el Modulo Portal: " + portal.getIdModulo(), e);
			}
				
		}
		return creado;
	}
		
		
	@Override
	public boolean actualizarPortal(PortalDto portal) throws ConfigException {
		
		boolean actualizado= false;
		Portal portalEntity=null;
		
		if (portal!=null){
			try {
				portalEntity= this.em.find(Portal.class, portal.getIdModulo());
				if(portalEntity!=null){
					//this.em.getTransaction().begin();
					
					this.setPortal(portalEntity, portal);
					this.em.merge(portalEntity);
					
					
					//this.em.getTransaction().commit();
					
					actualizado=true;
				}
			} catch (Exception e) {
				/*if (this.em.getTransaction().isActive()){
					this.em.getTransaction().rollback();
					actualizado=false;
				}*/
				throw new ConfigException("No se puedo actualizar el Modulo Portal: "+ portal,e);
			}
		}else{
			actualizado= false;
			throw new ConfigException("No existe el Modulo Portal");
		}
		
		return actualizado;
	}

	@Override
	public boolean eliminarPortal(Integer nroPortal) throws ConfigException {
		boolean eliminado=false;
		Portal portalEntity=null;
		
		if (nroPortal!=null){
			try {
				portalEntity= this.em.find(Portal.class, nroPortal);
				if (portalEntity!=null){
					//this.em.getTransaction().begin();
					this.em.remove(portalEntity);
					eliminado=true;
				}
			} catch (Exception e) {
				/*if (this.em.getTransaction().isActive()){
					this.em.getTransaction().rollback();
					eliminado=false;
				}*/
				
				eliminado=false;
				throw new ConfigException("No se puedo eliminar el Modulo Portal: "+nroPortal,e);
			}
		}
		return eliminado;
	}

	@Override
	public PortalDto buscarPortal(Integer nroPortal) throws ConfigException {
		
		PortalDto portalDto=null;
		
		try {
			Portal portal =this.em.find(Portal.class, nroPortal);
			
			if (portal!=null){
				portalDto= this.transformer.toPortalDto(portal);
			}
		} catch (Exception e) {
			throw new ConfigException("Error al procesar la busqueda del Portal", e);
		}
		return portalDto;
	}

	@Override
	public boolean eliminaPortales(List<PortalDto> portales)throws ConfigException {
		
		boolean eliminados=false;

		try {
			//this.em.getTransaction().begin();
			
			if(portales!=null){
				for(PortalDto portal: portales){
					Portal portalEntity= this.transformer.toPortalEntity(portal);
					this.em.remove(portalEntity);
				}
			//	this.em.getTransaction().commit();
				eliminados=true;
			}
		} catch (Exception e) {
			/*if (this.em.getTransaction().isActive()){
				this.em.getTransaction().rollback();
			}*/
			throw new ConfigException("No se pudieron eliminar los modulos Portal", e);
		}
	return eliminados;
	
	}

	@Override
	public List<PortalDto> listarPortales() throws ConfigException {
		List<PortalDto> portalesDto=null;
		List<Portal> portales=null;
		
		try {
			TypedQuery<Portal> query= this.em.createQuery("Select p from Portal p", Portal.class);
			portales= query.getResultList();
			if (portales!=null){
				if (portales.size()>0){
					portalesDto = new ArrayList<PortalDto>();
					for (Portal portal:portales){
						PortalDto portalDto= this.transformer.toPortalDto(portal);
						portalesDto.add(portalDto);
					}
				}
			}
		} catch (Exception e) {
			throw new ConfigException("Error al listar los Portales",e);
		}
		return portalesDto;
	}

	@Override
	public boolean crearDespacho(DespachoDto despacho) throws ConfigException {
		boolean creado=false;
		
		//this.em.getTransaction().begin();
		
		if (despacho!=null){
			Despacho despachoEntity= this.transformer.toDespachoEntity(despacho);
			
			try {
				if(buscarDespacho(despacho.getIdModulo())==null){
					this.em.persist(despachoEntity);
					creado=true;
				}
				else{
					//actualiza el despacho
					actualizarDespacho(despacho);
					creado = false;
				}
				
				//Le indica al Negocio que actualice la configuracion
				//actualizarNegocio();
				
			} catch (Exception e) {
				/*if (this.em.getTransaction().isActive()){
					this.em.getTransaction().rollback();
				}*/
				throw new ConfigException("No se puedo insertar el Modulo Despacho: " + despacho.getIdModulo(), e);
			}	
		}
		return creado;
	}
	

	@Override
	public boolean actualizarDespacho(DespachoDto despacho)throws ConfigException{
	boolean actualizado= false;
	
	Despacho despachoEntity=null;
	
	if (despacho!=null){
		try {
			despachoEntity= this.em.find(Despacho.class, despacho.getIdModulo());
			if(despachoEntity!=null){
				//this.em.getTransaction().begin();
				this.setDespacho(despachoEntity, despacho);
				this.em.merge(despachoEntity);
				
				//this.em.getTransaction().commit();
				actualizado=true;
			}
		} catch (Exception e) {
			/*if (this.em.getTransaction().isActive()){
				this.em.getTransaction().rollback();
				actualizado=false;
			}*/
			throw new ConfigException("No se puedo actualizar el Modulo Despacho: "+ despacho,e);
		}
		}else{
		actualizado= false;
		throw new ConfigException("No existe el Modulo Portal");
	}
	return actualizado;
	}

	@Override
	public boolean eliminarDespacho(Integer nroDespacho) throws ConfigException {
		
		boolean eliminado=false;
		Despacho despachoEntity=null;
		
		if (nroDespacho!=null){
			try {
				despachoEntity= this.em.find(Despacho.class, nroDespacho);
				if (despachoEntity!=null){
					//this.em.getTransaction().begin();
					this.em.remove(despachoEntity);
					eliminado=true;
				}
			} catch (Exception e) {
				/*if (this.em.getTransaction().isActive()){
					this.em.getTransaction().rollback();
					eliminado=false;
				}*/
				throw new ConfigException("No se puedo eliminar el Modulo Despacho: "+nroDespacho,e);
			}
		}
		return eliminado;
	}

	@Override
	public DespachoDto buscarDespacho(Integer nroDespacho)throws ConfigException {
		DespachoDto despachoDto=null;
		
		try {
			Despacho despacho =this.em.find(Despacho.class, nroDespacho);
			
			if (despacho!=null){
				despachoDto= this.transformer.toDespachoDto(despacho);
			}
		} catch (Exception e) {
			throw new ConfigException("Error al procesar la busqueda del despacho", e);
		}
		return despachoDto;
	}

	@Override
	public boolean eliminaDespachos(List<DespachoDto> despachos) throws ConfigException {
		boolean eliminados=false;

		try {
			//this.em.getTransaction().begin();
			if(despachos!=null){
				for(DespachoDto despacho: despachos){
					Despacho despachoEntity= this.transformer.toDespachoEntity(despacho);
					this.em.remove(despachoEntity);
				}
				//this.em.getTransaction().commit();
				eliminados=true;
			}
		} catch (Exception e) {
			/*if (this.em.getTransaction().isActive()){
				this.em.getTransaction().rollback();
			}*/
			throw new ConfigException("No se pudieron eliminar los modulos Despacho ", e);
		}
	return eliminados;
	}

	@Override
	public List<DespachoDto> listarDespachos() throws ConfigException {
		
		List<DespachoDto> despachosDto=null;
		List<Despacho> despachos=null;
		
		try {
			TypedQuery<Despacho> query= this.em.createQuery("Select d from Despacho d ", Despacho.class);
			despachos= query.getResultList();
			if (despachos!=null){
				if (despachos.size()>0){
					despachosDto = new ArrayList<DespachoDto>();
					for (Despacho despacho:despachos){
						DespachoDto despachoDto= this.transformer.toDespachoDto(despacho);
						despachosDto.add(despachoDto);
					}
				}
			}
		} catch (Exception e) {
			throw new ConfigException("Error al listar los Portales",e);
		}
		return despachosDto;
	}

	@Override
	public boolean crearDeposito(DepositoDto deposito) throws ConfigException {
		boolean creado=false;
		
		//this.em.getTransaction().begin();
		
		if (deposito!=null){
			Deposito depositoEntity= this.transformer.toDepositoEntity(deposito);
			try {
				if(buscarDeposito(deposito.getIdModulo())==null){
					this.em.persist(depositoEntity);
					creado=true;
				}
				else{
					//actualiza el deposito
					actualizarDeposito(deposito);
					creado=false;
				}
				
				//Le indica al Negocio que actualice la configuracion
				//actualizarNegocio();
				
			} catch (Exception e) {
				/*if (this.em.getTransaction().isActive()){
					this.em.getTransaction().rollback();
				}*/
				throw new ConfigException("No se puedo insertar el Modulo Deposito: " + deposito.getIdModulo(), e);
			}	
		}
		return creado;
	}

	@Override
	public boolean actualizarDeposito(DepositoDto deposito) throws ConfigException {
		boolean actualizado= false;
		
		Deposito depositoEntity=null;
		
		if (deposito!=null){
			try {
				depositoEntity= this.em.find(Deposito.class, deposito.getIdModulo());
				if(depositoEntity!=null){
					//this.em.getTransaction().begin();
					this.setDeposito(depositoEntity, deposito);
					this.em.merge(depositoEntity);
					//this.em.getTransaction().commit();
					actualizado=true;
				}
			} catch (Exception e) {
				/*if (this.em.getTransaction().isActive()){
					this.em.getTransaction().rollback();
					actualizado=false;
				}*/
				actualizado=false;
				throw new ConfigException("No se puedo actualizar el Modulo Deposito: "+ deposito,e);
			}
			}else{
			actualizado= false;
			throw new ConfigException("No existe el Modulo Deposito");
		}
		return actualizado;
	}

	@Override
	public boolean eliminarDeposito(Integer nroDeposito) throws ConfigException {
		boolean eliminado=false;
		Deposito depositoEntity=null;
		
		if (nroDeposito!=null){
			try {
				depositoEntity= this.em.find(Deposito.class, nroDeposito);
				if (depositoEntity!=null){
					//this.em.getTransaction().begin();
					this.em.remove(depositoEntity);
					eliminado=true;
				}
			} catch (Exception e) {
				/*if (this.em.getTransaction().isActive()){
					this.em.getTransaction().rollback();
					eliminado=false;
				}*/
				eliminado=false;
				throw new ConfigException("No se puedo eliminar el Modulo Deposito: "+nroDeposito,e);
			}
		}
		return eliminado;
	}

	@Override
	public DepositoDto buscarDeposito(Integer nroDeposito) throws ConfigException {
		DepositoDto depositoDto=null;
		
		try {
			Deposito deposito =this.em.find(Deposito.class, nroDeposito);
			
			if (deposito!=null){
				depositoDto= this.transformer.toDepositoDto(deposito);
			}
		} catch (Exception e) {
			throw new ConfigException("Error al procesar la busqueda del deposito", e);
		}
		return depositoDto;

	}

	@Override
	public boolean eliminaDepositos(List<DepositoDto> depositos) throws ConfigException {
		boolean eliminados=false;

		try {
			//this.em.getTransaction().begin();
			if(depositos!=null){
				for(DepositoDto deposito: depositos){
					Deposito depositoEntity= this.transformer.toDepositoEntity(deposito);
					this.em.remove(depositoEntity);
				}
				//this.em.getTransaction().commit();
				eliminados=true;
			}
		} catch (Exception e) {
			/*if (this.em.getTransaction().isActive()){
				this.em.getTransaction().rollback();
			}*/
			throw new ConfigException("No se pudieron eliminar los modulos Depositos ", e);
		}
	return eliminados;
	}

	@Override
	public List<DepositoDto> listarDepositos() throws ConfigException {
		
		List<DepositoDto> depositosDto=null;
		List<Deposito> depositos=null;
		
		try {
			TypedQuery<Deposito> query= this.em.createQuery("Select d from Deposito d ", Deposito.class);
			depositos= query.getResultList();
			
			if (depositos!=null){
				if (depositos.size() > 0) {
					depositosDto = new ArrayList<DepositoDto>();
					for (Deposito deposito:depositos){
						DepositoDto depositoDto= this.transformer.toDepositoDto(deposito);
						depositosDto.add(depositoDto);
					}
				}
			}
		} catch (Exception e) {
			throw new ConfigException("Error al listar los Depositos",e);
		}
		return depositosDto;
	}

	@Override
	public boolean crearLogistica(LogisticaDto logistica) throws ConfigException {
		boolean creado=false;
		
		//this.em.getTransaction().begin();
		
		if (logistica!=null){
			Logistica logisticaEntity= this.transformer.toLogisticaEntity(logistica);
			try {
				if(buscarLogistica(logistica.getIdModulo())==null){
					this.em.persist(logisticaEntity);
					creado=true;
				}
				else{
					//actualiza la logistica
					actualizarLogistica(logistica);
					creado=false;
				}
				
			} catch (Exception e) {
				/*if (this.em.getTransaction().isActive()){
					this.em.getTransaction().rollback();
				}*/
				throw new ConfigException("No se puedo insertar el Modulo Logistica: " + logistica.getIdModulo(), e);
			}	
			
			//Le indica al Negocio que actualice la configuracion
			//actualizarNegocio();
		}
		return creado;
	}

	@Override
	public boolean actualizarLogistica(LogisticaDto logistica) throws ConfigException {
		boolean actualizado= false;
		
		Logistica logisticaEntity=null;
		
		if (logistica!=null){
			try {
				logisticaEntity= this.em.find(Logistica.class, logistica.getIdModulo());
				if(logisticaEntity!=null){
					//this.em.getTransaction().begin();
					this.setLogistica(logisticaEntity, logistica);
					this.em.merge(logisticaEntity);
					//this.em.getTransaction().commit();
					actualizado=true;
				}
			} catch (Exception e) {
				/*if (this.em.getTransaction().isActive()){
					this.em.getTransaction().rollback();
					actualizado=false;
				}*/
				throw new ConfigException("No se puedo actualizar el Modulo Logistica: "+ logistica,e);
			}
			}else{
			actualizado= false;
			throw new ConfigException("No existe el Modulo Logistica");
		}
		return actualizado;
	}

	@Override
	public boolean eliminarLogistica(Integer nroLogistica) throws ConfigException {
		
		boolean eliminado=false;
		
		Logistica logisticaEntity=null;
		
		if (nroLogistica!=null){
			try {
				logisticaEntity= this.em.find(Logistica.class, nroLogistica);
				if (logisticaEntity!=null){
					//this.em.getTransaction().begin();
					this.em.remove(logisticaEntity);
					eliminado=true;
				}
			} catch (Exception e) {
				/*if (this.em.getTransaction().isActive()){
					this.em.getTransaction().rollback();
					eliminado=false;
				}*/
				throw new ConfigException("No se puedo eliminar el Modulo Logistica: "+nroLogistica,e);
			}
		}
		return eliminado;
	}

	@Override
	public LogisticaDto buscarLogistica(Integer nroLogistica) throws ConfigException {
		
		LogisticaDto logisticaDto=null;
		
		try {
			Logistica logistica =this.em.find(Logistica.class, nroLogistica);
			
			if (logistica!=null){
				logisticaDto= this.transformer.toLogisticaDto(logistica);
			}
		} catch (Exception e) {
			throw new ConfigException("Error al procesar la busqueda de Logistica", e);
		}
		return logisticaDto;
	}

	@Override
	public LogisticaDto listarLogistica() throws ConfigException {
		
		LogisticaDto logisticaDto=null;
		List<Logistica> logisticasEntity=null;
		
		try {
			TypedQuery<Logistica> query= this.em.createQuery("Select l from Logistica l ", Logistica.class);
			
			logisticasEntity= query.getResultList();
			
			if (logisticasEntity!=null) {
				if (logisticasEntity.size() > 0){
					
					Logistica logisticaEntity= logisticasEntity.get(0); //Obtengo solo el primero
					logisticaDto= this.transformer.toLogisticaDto(logisticaEntity);
				
				}
			}
			
		} catch (Exception e) {
			throw new ConfigException("Error al listar el modulo Logistica",e);
		}
		
		return logisticaDto;
		
	}

	/**
	 * Actualiza los datos modificados de Portal
	 * @param destPortal
	 * @param srcPortal
	 */
	private void setPortal(Portal destPortal, PortalDto srcPortal){
		destPortal.setDescripcion(srcPortal.getDescripcion());
		destPortal.setIpAddress(srcPortal.getIpAddress());
		destPortal.setUrl(srcPortal.getUrl());
	}
	
	/**
	 * Actualiza los datos modificados Despacho
	 * @param destDespacho
	 * @param srcDespacho
	 */
	
	private void setDespacho(Despacho destDespacho, DespachoDto srcDespacho){
		destDespacho.setDescripcion(srcDespacho.getDescripcion());
		destDespacho.setIpAddress(srcDespacho.getIpAddress());
	}
	
	/**
	 * Actualiza los datos modificados de Deposito
	 * @param destDeposito
	 * @param srcDeposito
	 */
	private void setDeposito(Deposito destDeposito, DepositoDto srcDeposito){
		destDeposito.setDescripcion(srcDeposito.getDescripcion());
		destDeposito.setIpAddress(srcDeposito.getIpAddress());
		
	}
	
	private void setLogistica(Logistica destLogistica, LogisticaDto srcLogistica){
		destLogistica.setDescripcion(srcLogistica.getDescripcion());
		destLogistica.setIpAddress(srcLogistica.getIpAddress());
		destLogistica.setSincronico(srcLogistica.getSincronico());
		
		destLogistica.setUrl(srcLogistica.getUrl());
		destLogistica.setColaJMS(srcLogistica.getColaJMS());
		destLogistica.setUserJMS(srcLogistica.getUserJMS());
		destLogistica.setPassJMS(srcLogistica.getPassJMS());
	}

	@Override
	public void eliminarTodosLosModulos() {
		this.em.createQuery("DELETE FROM Logistica").executeUpdate();
		this.em.createQuery("DELETE FROM Portal").executeUpdate();
		this.em.createQuery("DELETE FROM Deposito").executeUpdate();
		this.em.createQuery("DELETE FROM Despacho").executeUpdate();
	}	
}
